<?php

namespace App\Http\Repositories\Redis;

use App\Models\Users;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class UserRedis extends BaseRedis
{
    //类单例数组
    private static $instance = [];
    //redis连接句柄
    protected $_redis = false;
    protected $prefix = 'yxxcx:user_login';//redis key前缀
    protected static $configKey = 'user'; //默认的database内配置的连接的指定redis数据库
    protected $hashCacheTime = 15552000; //哈希表生存时间 半年
    protected $idKey = 'id';

    private function __construct($config)
    {
//        $this->prefix = config('app.name') . $this->prefix;
        $database     = $config['database'];
        if (isset($config['persistent']) && $config['persistent']) {
            $func = 'pconnect';
            //注意 $persistent_id 此处，持久连接设置标识
            $persistent_id = 'pconnect_' . $database;
        } else {
            $func          = 'connect';
            $persistent_id = null;
        }
        $this->_redis = new \Redis();
        $this->_redis->$func($config['host'], $config['port'], 0, $persistent_id);
        if ('' != $config['password']) {
            $this->_redis->auth($config['password']);
        }
        $this->_redis->select((int)$database);
    }

    /**
     * 获取类单例
     * @return self
     */
    public static function getRedisInstance()
    {
        $config   = config("database.redis." . self::$configKey);
        $database = $config['database'];
        $database = (int)$database;
        if (!isset(self::$instance[$database])) {
            self::$instance[$database] = new self($config);
        }
        return self::$instance[$database];
    }

    /**
     * 登录后，记录用户登录数据，会刷新token
     * @param $userId
     * @param array $aUser 用户登录时候的数据
     * @param $expireTime 过期时间
     * @param $type int 类型 1 app 2 h5
     * @return bool
     */
    public function setLogin($userId, $aUser, $expireTime, $type = 1)
    {
        if (!$this->_redis) {
            return false;
        }
        $aUser['login_time'] = date('Y-m-d H:i:s', time());
        Log::info('用户:' . $userId . '：login_time：' . Carbon::now()->toDateTimeString());
        if ($type == 1) {
            $key = $this->prefix . ":string:" . $userId;
        } else {
            $key = $this->prefix . ":string:h5:" . $userId;
        }
        $res = $this->_redis->SETEX($key, $expireTime, serialize($aUser));
        Log::info('res：' . $res . '：data：key-' . $key . '：expire_time-' . $expireTime . '：data-' . serialize($aUser));
        return $res;
    }

    /**
     * 检测用户登录token，同时只允许一个设备登录
     * @param $userId
     * @param $token
     * @param $type int 类型 1 app 2 h5
     * @return bool
     */
    public function checkLoginToken($userId, $token, $type = 1)
    {
        if (!$this->_redis) {
            return true;
        }
        if ($type == 1) {
            $key = $this->prefix . ":string:" . $userId;
        } else {
            $key = $this->prefix . ":string:h5:" . $userId;
        }
        $ret = $this->_redis->GET($key);
        if ($type == 1) {
            if (!$ret) {//不存在记录也过
                return true;
            }
        }
        $aUser = $ret ? unserialize($ret) : [];
        if (isset($aUser['token']) && $aUser['token'] == $token) {
            return true;
        } else {
            //过期
            $dbToken = isset($aUser['token']) ? $aUser['token'] : '无';
            Log::info('登录token验证失败，user_id：' . $userId . '，token：' . $token . '，db_token：' . $dbToken);
            return false;
        }
    }

    /**
     * 用户手动退出登录状态 消除数据
     * @param $userId
     * @return bool
     */
    public function setLogout($userId, $type = 2)
    {
        if (!$this->_redis) {
            return false;
        }
        if ($type == 1) {
            $key = $this->prefix . ":string:" . $userId;
        } else {
            $key = $this->prefix . ":string:h5:" . $userId;
        }
        $ret = $this->_redis->EXISTS($key);
        if ($ret) {
            return $this->_redis->DEL($key);
        }
        return true;
    }

    /**
     * 从数据库获取完整节点数据
     * @param $id
     * @return array
     */
    public function getDbNode($id)
    {
        $field = ['id', 'nickname', 'mobile', 'openid', 'email', 'avatar', 'created_at', 'status','role_id'];
        return Users::where('id', $id)->first($field)->toArray();
    }


    /**
     * 没有的方法调redis的吧
     * @param $name
     * @param $arguments
     * @return mixed
     */
    public function __call($name, $arguments)
    {
        $res = call_user_func_array(array($this->_redis, $name), $arguments);

        return $res;
    }
}
